from ...service.common import LoginType, get_current_user_id, get_current_organization_id, get_current_role_id, set_current_org_id, set_current_role_id, set_current_user_id, get_indentify_id, get_info, get_user_id_or_false
from ...service.buss_pub.bill_manage import BillManageService, OperationType, TypeId, Status
from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.mongo_bill_service import MongoBillFilter
from ...service.buss_pub.sms_manage import SmsManageService
import hashlib
import uuid
import datetime
import random
from ...pao_python.pao.data import get_cur_time
from ...service.buss_mis.financial_account import FinancialAccountObject
from ...service.constant import (AccountStatus, AccountType, PayStatue,
                                 PayType, plat_id)
'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-09-25 09:48:29
@LastEditTime: 2020-03-11 10:02:31
@LastEditors: Please set LastEditors
'''

'''
版权：Copyright (c) 2019 China

创建日期：Thursday September 12th 2019
创建者：ymq(ymq) - <<email>>

修改日期: Thursday, 12th September 2019 10:09:34 am
修改者: ymq(ymq) - <<email>>

说明
 1、注册，登录模块
'''


class LoginService(MongoService):

    user_collection = 'PT_User'
    role_collection = 'PT_Role'
    permission_collection = 'PT_Permission'
    set_role = 'PT_Set_Role'
    fail_res = 'Fail'
    success_res = 'Success'

    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.db_user = db_user
        self.db_pwd = db_pwd
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_service = BillManageService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)
        self.sms_manage_service = SmsManageService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)

    def login(self, login_data):
        '''登录
        Args：
            login_data:关键字包括：login_type,account_name,password
        Return:
        返回结果为0代表用户不存在，即用户名不存在
        返回结果为-1代表密码错误，用户名存在
        '''
        res = self.fail_res
        if login_data['login_type'] == LoginType.account:
            password_tep = hashlib.sha256(
                login_data['password'].encode('utf-8'))
            password = password_tep.hexdigest()
            _filter = MongoBillFilter()
            _filter.match_bill((C('login_info.login_type') == LoginType.account)
                               & (C('login_info.login_check.account_name') == login_data['account_name']))
            tep_data = self.query(_filter, self.user_collection)
            if len(tep_data) > 0:
                if tep_data[0]['login_info'][0]['login_check']['password'] == password:
                    set_current_user_id(
                        self.session, tep_data[0]['id'])
                    res = self.success_res
                else:
                    res = -1
            else:
                res = 0
        return res

    def get_role_list(self):
        '''获取登录用户的角色列表'''
        user_id = get_current_user_id(self.session)
        _filter = MongoBillFilter()
        _filter.match_bill(C('principal_account_id') == user_id)\
               .inner_join_bill('PT_User', 'principal_account_id', 'id', 'user')\
               .inner_join_bill('PT_User', 'role_of_account_id', 'id', 'organization')\
               .inner_join_bill('PT_Role', 'role_id', 'id', 'role')\
               .project({'_id': 0, 'user._id': 0, 'organization._id': 0, 'role._id': 0, })
        res = self.query(_filter, self.set_role)
        return res

    def get_function_list(self):
        '''获取登录用户角色的功能列表'''
        role_id = get_current_role_id(self.session)
        _filter = MongoBillFilter()
        _filter.match_bill(C('role_id') == role_id)\
            .project({'_id': 0, })
        res = self.query(_filter, self.permission_collection)
        return res

    def get_permission_list(self, function_name, permission_name):
        '''获取登录用户角色某个功能，权限的列表'''
        role_id = get_current_role_id(self.session)
        print('角色id   ', role_id, function_name, permission_name)
        _filter = MongoBillFilter()
        _filter.match_bill((C('role_id') == role_id) & (C('function') == function_name)
                           & (C('permission') == permission_name))\
               .project({'_id': 0})
        res = self.query(_filter, self.permission_collection)
        return res

    def set_role_org_session(self, role_id, org_id):
        '''选择角色后，将角色id和角色所属账号id放入session中'''
        set_current_org_id(self.session, org_id)
        set_current_role_id(self.session, role_id)
        return 'Success'

    def add_user_data(self, data):
        '''新增用户表数据'''
        res = self.fail_res
        data['reg_date'] = datetime.datetime.now()
        bill_id = self.bill_manage_service.add_bill(
            OperationType.add.value, TypeId.user.value, data, self.user_collection)
        if bill_id:
            res = self.success_res
        return res

    def add_role_data(self, data):
        '''新增角色表数据'''
        res = self.fail_res
        data['date'] = datetime.datetime.now()
        bill_id = self.bill_manage_service.add_bill(
            OperationType.add.value, TypeId.user.value, data, self.role_collection)
        if bill_id:
            res = self.success_res
        return res

    def add_permission_data(self, data):
        '''新增权限表数据'''
        res = self.fail_res
        data['date'] = datetime.datetime.now()
        bill_id = self.bill_manage_service.add_bill(
            OperationType.add.value, TypeId.user.value, data, self.permission_collection)
        if bill_id:
            res = self.success_res
        return res

    def add_set_role_data(self, data):
        '''新增角色设置表数据'''
        res = self.fail_res
        data['date'] = datetime.datetime.now()
        bill_id = self.bill_manage_service.add_bill(
            OperationType.add.value, TypeId.user.value, data, self.set_role)
        if bill_id:
            res = self.success_res
        return res

    def bind_mobile(self, mobile, identify_code):
        ''' 绑定手机号码'''
        res = self.fail_res
        # if self.session[self.indentify] != identify_code :
        if identify_code != '1234':
            return '验证码错误'
        else:
            user_id = get_current_user_id(self.session)
            _filter = MongoBillFilter()
            _filter.match_bill((C('id') == user_id))\
                .project({'_id': 0})
            res = self.query(_filter, self.user_collection)
            if len(res) > 0:
                personnel_info = res[0]['personnel_info']
                personnel_info['telephone'] = mobile
                data = {'id': user_id, 'personnel_info': personnel_info}
                bill_id = self.bill_manage_service.add_bill(
                    OperationType.update.value, TypeId.user.value, data, self.user_collection)
                if bill_id:
                    res = self.success_res
        return res

    def modify_email(self, new_email, identify_code):
        ''' 绑定邮箱'''
        res = self.fail_res
        # if self.session[self.indentify] != identify_code :
        if identify_code != '1234':
            return '验证码错误'
        else:
            user_id = get_current_user_id(self.session)
            _filter = MongoBillFilter()
            _filter.match_bill((C('id') == user_id))\
                .project({'_id': 0})
            res = self.query(_filter, self.user_collection)
            if len(res) > 0:
                personnel_info = res[0]['personnel_info']
                personnel_info['email'] = new_email
                data = {'id': user_id, 'personnel_info': personnel_info}
                bill_id = self.bill_manage_service.add_bill(
                    OperationType.update.value, TypeId.user.value, data, self.user_collection)
                if bill_id:
                    res = '绑定成功'
        return res

    def check(self, target, target_type, identify_code):
        # 重置密码的身份验证
        user_id = get_current_user_id(self.session)
        identify_session = get_indentify_id(self.session)
        if target_type == 'mobile':
            _filter = MongoBillFilter()
            _filter.match_bill((C('id') == user_id) & (
                C('personnel_info.telephone') == target))
        elif target_type == 'email':
            _filter = MongoBillFilter()
            _filter.match_bill((C('id') == user_id) & (
                C('personnel_info.email') == target))
        query_res = self.query(_filter, 'PT_User')
        if len(query_res) == 0:
            return False
        # elif self.session[self.indentify] == identify_code and get_current_account_id(self.session)==query_df['id'].iloc[0] :
        elif identify_code == identify_session:
            return True
        else:
            return False

    def modify_user_info(self, new_info):
        # 修改个人资料
        print("前端传过来的数据", new_info['key'])
        account_id = get_current_user_id(self.session)
        _filter = MongoBillFilter()
        _filter.match_bill((C('id') == account_id))\
            .project({'_id': 0, })
        query_res = self.query(_filter, 'PT_User')
        user = query_res[0]
        if "name" == new_info['key']:
            user['name'] = new_info['value']
        if "account_name" == new_info['key']:
            user['login_info'][0]['login_check']['account_name'] = new_info['value']
        if "password" == new_info['key']:
            newpassword_tep = hashlib.sha256(new_info['value'].encode('utf-8'))
            newpassword = newpassword_tep.hexdigest()
            user['login_info'][0]['login_check']['password'] = newpassword
        if "telephone" == new_info['key']:
            user['personnel_info']['telephone'] = new_info['value']
        if "address" == new_info['key']:
            user['personnel_info']['address'] = new_info['value']
        if "photo" == new_info['key']:
            user['personnel_info']['picture_list'] = new_info['value']
        if "id_card" == new_info['key']:
            user['personnel_info']['id_card'] = new_info['id_card']
        if 'id' == new_info['key']:
            user['name'] = new_info['value']['name']
            user['id_card'] = new_info['value']['id_card']
            user['admin_area_id'] = new_info['value']['admin_area_id']
            user['personnel_info']['card_type'] = new_info['value']['card_type']
            user['personnel_info']['date_birth'] = new_info['value']['date_birth']
            user['personnel_info']['is_address_type'] = new_info['value']['is_address_type']
            user['personnel_info']['native_place'] = new_info['value']['native_place']
            user['personnel_info']['telephone'] = new_info['value']['telephone']
            user['personnel_info']['address'] = new_info['value']['address']
            user['personnel_info']['sex'] = new_info['value']['sex']
            user['personnel_info']['id_card'] = new_info['value']['id_card']
        bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
                                                    TypeId.user.value, user, 'PT_User')
        if bill_id:
            return 'Successs'

    # def modify_password(self, new_password):
    #     # 修改密码
    #     newpassword_tep = hashlib.sha256(new_password.encode('utf-8'))
    #     newpassword = newpassword_tep.hexdigest()
    #     print("新密码》》", newpassword)
    #     if new_password == self.inital_password:
    #         return False
    #     else:
    #         account_id = get_current_user_id(self.session)
    #         _filter = MongoBillFilter()
    #         _filter.match_bill((C('id') == account_id))\
    #             .project({'_id': 0, })
    #         query_res = self.query(_filter, 'PT_User')
    #         user = query_res[0]
    #         user['login_info'][0]['login_check']['password'] = newpassword
    #         bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
    #                                                     TypeId.user.value, user, 'PT_User')
    #         if bill_id:
    #             return 'Successs'
    #         return False

    def register(self, register_data):
        '''注册
        Args：
            login_data:关键字包括：login_type,account_name,password
        Return:
        '''
        # 短信验证码验证
        # 字段必须
        if 'verifyCode' not in register_data:
            return '必须输入验证码！'
        # 验证合法性
        if self.sms_manage_service.verifyCode('register', register_data['mobile'], register_data['verifyCode']) != True:
            return '验证码不正确！'

        # if 'admin_area_id' not in register_data or register_data['admin_area_id'] =='':
        #     # 默认绑定平台,并查找平台所属的区划
        #     _filter = MongoBillFilter()
        #     _filter.match_bill((C('id') == '7e7e2fec-d91d-11e9-8e1d-983b8f0bcd67'))\
        #         .project({'_id': 0})
        #     areaInfo = self.query(_filter, 'PT_User')
        #     areaId = areaInfo[0]['admin_area_id']
        # else:
        #     areaId = register_data['admin_area_id']

        # 判断手机号码是否已经注册
        if 'mobile' not in register_data:
            return '必须输入手机号码！'

        _filter_mobile = MongoBillFilter()
        _filter_mobile.match_bill((C('personnel_info.telephone') == register_data['mobile']))\
            .project({'_id': 0})
        mobileInfo = self.query(_filter_mobile, 'PT_User')

        if len(mobileInfo) > 0:
            return '当前手机号码已经注册！'

        login_info = [
            {
                "login_type": "account",
                'login_check': {}
            }
        ]
        data_dict = {
            'personnel_info': {},
            'login_info': login_info
        }
        res = self.fail_res

        # 获取默认平台的组织ID和区域ID
        _filter_pt = MongoBillFilter()
        _filter_pt.match_bill((C('personnel_type') == '2') & (C('organization_info.personnel_category') == '平台'))\
            .project({'_id': 0})
        ogInfo = self.query(_filter_pt, 'PT_User')

        if len(ogInfo) > 0:
            if 'id' in ogInfo[0]:
                data_dict['organization_id'] = ogInfo[0]['id']
            if 'admin_area_id' in ogInfo[0]:
                data_dict['admin_area_id'] = ogInfo[0]['admin_area_id']

        data_dict['id'] = str(uuid.uuid1())
        data_dict['name'] = register_data['name']
        data_dict['id_card'] = register_data['id_card']
        data_dict['id_card_type'] = "身份证"
        data_dict["personnel_type"] = '1'
        data_dict['personnel_info']['personnel_category'] = '游客'
        data_dict['personnel_info']['id_card'] = register_data['id_card']
        login_info[0]['login_type'] = "account"
        login_info[0]['login_check']['account_name'] = register_data['accountName']
        login_info[0]['login_check']['password'] = hashlib.sha256(
            register_data['password'].encode('utf-8')).hexdigest()
        # data_dict['login_info']['login_check']['account_name'] = register_data['userName']
        # data_dict['login_info']['login_check']['password'] = hashlib.sha256(
        #     register_data['password'].encode('utf-8')).hexdigest()
        data_dict['personnel_info']['telephone'] = register_data['mobile']
        # 补充时间
        data_dict['create_date'] = get_cur_time()
        set_role = {'role_id': '8ed260f6-e355-11e9-875e-a0a4c57e9ebe',
                    'principal_account_id': data_dict['id'], 'role_of_account_id': ogInfo[0]['id']}

        # 这里要做一个判断是否已存在该人员的判断：没有登录账号信息则合并，有登录账号信息则提示已存在
        _filter = MongoBillFilter()
        _filter.match_bill((C('name') == register_data['name']) & (C('id_card') == register_data['id_card']))\
            .project({'_id': 0, })
        query_res = self.query(_filter, 'PT_User')

        # 未登录的情况下，用这个
        bill_manage_service2 = BillManageService(
            self.db_addr, self.db_port, self.db_name, self.db_user, self.db_pwd, self.inital_password, {
                'user_id': '23b3630a-d92c-11e9-8b9a-983b8f0bcd67',
                'organization_id': data_dict['organization_id']
            })

        if len(query_res) > 0:
            if 'account_name' in query_res[0]['login_info'][0]['login_check'].keys() and query_res[0]['login_info'][0]['login_check']['account_name'] != '':
                '''有登录账号信息则提示已存在'''
                return '该长者：'+register_data['name'] + '已存在，无需重新注册'
            else:
                '''没有登录账号信息则合并'''
                bill_id = bill_manage_service2.add_bill(OperationType.add.value,
                                                        TypeId.user.value, [set_role], ['PT_Set_Role'])
                data_dict['id'] = query_res[0]['id']
                bill_id = bill_manage_service2.add_bill(OperationType.update.value,
                                                        TypeId.user.value, [data_dict], ['PT_User'])
                if bill_id:
                    res = 'Success'
        else:
            ''' 新增用户 '''

            # 主数据的数据
            data_dict['create_date'] = get_cur_time()
            # 新增账户信息（1个机构储蓄、1个app储蓄、1个真实账户、1个补贴账户）
            # 机构储蓄对象
            org_account_data = FinancialAccountObject(
                AccountType.account_recharg_wel, data_dict['id'], data_dict['organization_id'], AccountStatus.normal, 1, AccountType.account_recharg_wel, {}, 0)

            org_account = org_account_data.to_dict()
            org_account['id'] = str(uuid.uuid1())
            org_account['create_date'] = get_cur_time()
            org_account['organization_id'] = data_dict['organization_id']
            # app储蓄对象
            app_account_data = FinancialAccountObject(
                AccountType.account_recharg_app, data_dict['id'], plat_id, AccountStatus.normal, 2, AccountType.account_recharg_app, {}, 0)
            app_account = app_account_data.to_dict()
            app_account['id'] = str(uuid.uuid1())
            app_account['create_date'] = get_cur_time()
            app_account['organization_id'] = data_dict['organization_id']
            # 真实账户对象
            real_account_data = FinancialAccountObject(
                AccountType.account_real, data_dict['id'], None, AccountStatus.normal, 3, AccountType.account_real, {}, 0)
            real_account = real_account_data.to_dict()
            real_account['id'] = str(uuid.uuid1())
            real_account['create_date'] = get_cur_time()
            real_account['organization_id'] = data_dict['organization_id']
            # 补贴账户对象
            subsidy_account_data = FinancialAccountObject(
                AccountType.account_subsidy, data_dict['id'], None, AccountStatus.normal, 4, AccountType.account_subsidy, {}, 0)
            subsidy_account = subsidy_account_data.to_dict()
            subsidy_account['id'] = str(uuid.uuid1())
            subsidy_account['create_date'] = get_cur_time()
            subsidy_account['organization_id'] = data_dict['organization_id']
            # 慈善账户
            charitable_account_data = FinancialAccountObject(
                AccountType.account_charitable, data_dict['id'], None, AccountStatus.normal, 5, AccountType.account_charitable, {}, 0)
            charitable_account = charitable_account_data.to_dict()
            charitable_account['id'] = str(uuid.uuid1())
            charitable_account['create_date'] = get_cur_time()
            charitable_account['organization_id'] = data_dict['organization_id']

            account_data = [org_account, app_account,
                            real_account, subsidy_account, charitable_account]

            bill_id = bill_manage_service2.add_bill(OperationType.add.value,
                                                    TypeId.user.value, [account_data, [data_dict], [set_role]], ['PT_Financial_Account', 'PT_User', 'PT_Set_Role'])
            if bill_id:
                res = 'Success'
        return res

    # 忘记密码流程
    def retrieve_password(self, data):

        # 合法字段验证
        if 'type' not in data or 'telephone' not in data or 'password' not in data:
            return '非法数据！'

        # 短信验证码验证
        # 字段必须
        if 'code' not in data:
            return '必须输入验证码！'
        # 验证合法性
        if self.sms_manage_service.verifyCode('retrieve', data['telephone'], data['code']) != True:
            return '验证码不正确！'

        # 找出这个用户
        _filter = MongoBillFilter()
        _filter.match_bill((C('personnel_info.telephone') == data['telephone']))\
            .project({'_id': 0, })
        result = self.query(_filter, 'PT_User')

        if len(result) == 0:
            return '找不到绑定当前手机号的用户！'

        # 修改密码
        newpassword_tep = hashlib.sha256(data['password'].encode('utf-8'))
        newpassword = newpassword_tep.hexdigest()

        user = result[0]
        user['login_info'][0]['login_check']['password'] = newpassword

        # 未登录的情况下，用这个
        bill_manage_service2 = BillManageService(
            self.db_addr, self.db_port, self.db_name, self.db_user, self.db_pwd, self.inital_password, {
                'user_id': user['id'],
                'organization_id': user['organization_id']
            })
        bill_id = bill_manage_service2.add_bill(OperationType.update.value,
                                                TypeId.user.value, user, 'PT_User')
        if bill_id:
            return 'Success'
        return '修改失败！'

    # 修改手机流程
    def modify_mobile(self, data):

        # 合法字段验证
        if 'telephone' not in data:
            return '非法数据！'

        # 验证用户是否登录
        user_id = get_user_id_or_false(self.session)

        if user_id == False:
            return '用户未登录！'

        # 短信验证码验证
        # 字段必须
        if 'code' not in data:
            return '必须输入验证码！'
        # 验证合法性
        if self.sms_manage_service.verifyCode('modifyMobile', data['telephone'], data['code']) != True:
            return '验证码不正确！'

        # 判断这个手机号码是否被占用
        _filter_telephone = MongoBillFilter()
        _filter_telephone.match_bill((C('personnel_info.telephone') == data['telephone']))\
            .project({'_id': 0, })
        result_telephone = self.query(_filter_telephone, 'PT_User')

        if len(result_telephone) > 0 and result_telephone[0]['id'] != user_id:
            return '该手机号码已被注册！'

        # 找出这个用户
        _filter = MongoBillFilter()
        _filter.match_bill((C('id') == user_id))\
            .project({'_id': 0, })
        result = self.query(_filter, 'PT_User')

        if len(result) == 0:
            return '找不到修改目标！'

        # 在这里排除是否同手机号的问题
        if result[0]['personnel_info']['telephone'] == data['telephone']:
            return '新号码与旧号码相同，无需修改！'

        # 修改手机号码
        user = result[0]
        user['personnel_info']['telephone'] = data['telephone']
        bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
                                                    TypeId.user.value, user, 'PT_User')
        if bill_id:
            return 'Success'
        return '修改失败！'

    # 修改密码流程
    def modify_password(self, data):
        # 修改密码有步骤，必传
        if 'step' not in data:
            return '非法操作！'

        if data['step'] == 1:
            # 第一步，验证验证码是否成功

            # 短信验证码验证
            # 字段必须
            if 'code' not in data:
                return '必须输入验证码！'

            # 获取登录用户的手机号码

            # 获取当前登录的用户id
            user_id = get_user_id_or_false(self.session)

            if user_id == False:
                return '用户未登录！'

            # 找出这个用户
            _filter_user = MongoBillFilter()
            _filter_user.match_bill((C('id') == user_id))\
                .project({'_id': 0, })
            result_user = self.query(_filter_user, 'PT_User')

            if len(result_user) == 0:
                return '未知错误，请重新登录！'

            if 'personnel_info' not in result_user[0] or 'telephone' not in result_user[0]['personnel_info']:
                return '未绑定手机号码！'
            # 手机号码
            telephone = result_user[0]['personnel_info']['telephone']

            # 验证合法性
            if self.sms_manage_service.verifyCode('modifyPassword', telephone, data['code']) != True:
                return '验证码不正确！'

            # 设置session
            # self.session['mpCfg'] = {
            #     'userid': user_id,
            #     'expire': datetime.datetime.now()+datetime.timedelta(minutes=10)
            # }
            return 'Success'
        elif data['step'] == 2:
            # 第二步，修改密码
            # if 'password' not in data or 'mpCfg' not in self.session.keys():
            #     return '非法操作！'

            # mpCfg = self.session['mpCfg']

            mpCfg = {
                'userid': '23b3630a-d92c-11e9-8b9a-983b8f0bcd67',
                'expire': datetime.datetime.now()+datetime.timedelta(minutes=10)
            }

            # 判断是否在时间范围里
            # if get_cur_time() > mpCfg['expire']:
            #     return '修改超过十分钟有效期，请重新验证！'

            # 找出这个用户
            _filter_user = MongoBillFilter()
            _filter_user.match_bill((C('id') == mpCfg['userid']))\
                .project({'_id': 0, })
            result_user = self.query(_filter_user, 'PT_User')

            #
            if len(result_user) == 0:
                return '未知错误，请重新登录！'

            user = result_user[0]

            # 修改密码
            newpassword_tep = hashlib.sha256(data['password'].encode('utf-8'))
            newpassword = newpassword_tep.hexdigest()

            if newpassword == user['login_info'][0]['login_check']['password']:
                return '新密码和旧密码相同，无需更改！'

            user['login_info'][0]['login_check']['password'] = newpassword

            bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
                                                        TypeId.user.value, user, 'PT_User')
            if bill_id:
                # del(self.session['mpCfg'])
                return 'Success'
            return '修改失败！'
